package se.statifyme.server;

import java.util.logging.Logger;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import se.statifyme.shared.NoUserLoggedInException;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;

public enum AccessService {
	INSTANCE;
	
	public static final String TEST_USER_ID = "TestUserID";
	public static final String TEST_USER_EMAIL = "Test.Testsson@gmail.com";
	public static final String TEST_USER_AUTH_DOMAIN = "test.com";
	private static final String SESSION_TEST_ACCESS = "TEST_ACCESS";
	
	public String getNickname(ServletRequest request) throws NoUserLoggedInException {
		return getUser(request).getEmail();
	}
	
	public String getUserId(ServletRequest request) throws NoUserLoggedInException {
		return getUser(request).getUserId();
	}
	
	public boolean hasAccess(ServletRequest request) {
		return hasUserAccesss() || hasTestAccess(request);
	}
	
	public void setupTestAccess(ServletRequest request) {
		HttpSession session = ((HttpServletRequest) request).getSession(true);
		session.setAttribute(SESSION_TEST_ACCESS, Boolean.TRUE);
	}
	
	private User getUser(ServletRequest request) {
		User result;
		UserService userService = UserServiceFactory.getUserService();
		if (userService.isUserLoggedIn()) {
			result = userService.getCurrentUser();
			Logger.getLogger("StatifyMe").info("Returning user: " + result);
		} else if (hasTestAccess(request)) {
			result = new User(TEST_USER_EMAIL, TEST_USER_AUTH_DOMAIN, TEST_USER_ID);
			Logger.getLogger("StatifyMe").info("Returning TEST user: " + result);
		} else {
			throw new NoUserLoggedInException("Unable to get user since no user is logged in.");
		}
		return result;
	}
	
	private boolean hasTestAccess(ServletRequest request) {
		boolean result = false;
		HttpSession session = ((HttpServletRequest) request).getSession(false);
		if (session != null) {
			Boolean testAccess = (Boolean) session.getAttribute(SESSION_TEST_ACCESS);
			result = testAccess != null && testAccess.booleanValue();
		}
		return result;
	}
	
	private boolean hasUserAccesss() {
		UserService userService = UserServiceFactory.getUserService();
		return userService.isUserLoggedIn();
	}
}
